package fr.pud.client.model;

import java.io.Serializable;

import org.openstreetmap.gui.jmapviewer.Coordinate;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

import fr.pud.client.i18n.LanguagesConstants;
import fr.pud.utils.DOMParser;

/**
 * The representation of a station.
 * Apr 9, 2012 - OSE.
 * @author Simon Devineau, Adrien Hierry, Leopold Houdin, Pierre Reliquet
 *         Ecole des Mines de Nantes
 *         PUDStation.java
 * @param <T>
 */
public class PUDStation implements Serializable {
    /**
     * the serial UID.
     */
    private static final long  serialVersionUID         = -3972233827854127595L;
    /**
     * The number of arguments for the constructor Object[].
     */
    protected static final int STATION_ARGUMENTS_NUMBER = 4;
    /**
     * The address of the station.
     */
    private Address            address;
    /**
     * The opening time.
     */
    private Time               opening;
    /**
     * The closing time.
     */
    private Time               closing;
    /**
     * The loading time.
     */
    private int                loadingTime;

    /**
     * Default constructor
     * Put all the variables to zero.
     */
    public PUDStation() {
        super();
        this.address = new Address();
        this.opening = new Time();
        this.closing = new Time();
        this.loadingTime = 1;
    }

    /**
     * Constructor, sets the address up but not the other variables.
     * @param anAddress
     *            the address to add.
     */
    public PUDStation(Address anAddress) {
        this();
        this.address = anAddress;
    }

    /**
     * Constructs a station from a adress and the opening & closing time.
     * @param add
     *            the address
     * @param a
     *            the opening time
     * @param b
     *            the closing time.
     */
    public PUDStation(Address add, Time a, Time b) {
        this.address = add;
        this.opening = a;
        this.closing = b;
        this.loadingTime = 1;
    }

    /**
     * Constructs a station from an address and the opening & closing time & a
     * loading time.
     * @param add
     *            the address
     * @param a
     *            the opening time
     * @param b
     *            the closing time
     * @param aLoadingTime
     *            the loading time.
     */
    public PUDStation(Address add, Time a, Time b, int aLoadingTime) {
        this.address = add;
        this.opening = a;
        this.closing = b;
        this.loadingTime = aLoadingTime;
    }

    /**
     * Constructs a station from a Coordinate.
     * @param c
     *            the coordinate.
     */
    public PUDStation(Coordinate c) {
        this();
        this.address = new Address(c);
    }

    /**
     * Constructs a station from an array of objects which contains all the
     * variables.
     * @param o
     *            the array of object.
     */
    public PUDStation(Object[] o) {
        this.address = (Address) o[0];
        this.opening = new Time(o[1].toString());
        this.closing = new Time(o[2].toString());
        this.loadingTime = Integer.parseInt(o[3].toString());
    }

    @Override
    public boolean equals(Object obj) {
        if (obj instanceof PUDStation) {
            return ((PUDStation) obj).getAddress().equals(this.getAddress());
        }
        return false;
    }

    /**
     * @return the address.
     */
    public Address getAddress() {
        return this.address;
    }

    /**
     * @return the closing time.
     */
    public Time getClosing() {
        return this.closing;
    }

    /**
     * @return the LoadingTime
     */
    public int getLoadingTime() {
        return this.loadingTime;
    }

    /**
     * @return the opening time.
     */
    public Time getOpening() {
        return this.opening;
    }

    /**
     * Changes the address.
     * @param a
     *            the new address.
     */
    public void setAddress(Address a) {
        this.address = a;
    }

    /**
     * Changes the closing time
     * @param opening
     *            the new closing time
     */
    public void setClosing(Time closing) {
        this.closing = closing;
    }

    /**
     * @param isLoadingTime
     *            the isLoadingTime to set
     */
    public void setLoadingTime(int isLoadingTime) {
        this.loadingTime = isLoadingTime;
    }

    /**
     * Changes the opening time
     * @param opening
     *            the new opening time
     */
    public void setOpening(Time opening) {
        this.opening = opening;
    }

    public String toHTML() {
        String toReturn = "";
        toReturn += this.address
                + "test <br/>"
                + LanguagesConstants.LANGUAGE
                        .getString(LanguagesConstants.HOURS)
                + " : "
                + this.opening
                + "-"
                + this.closing
                + "   &&   "
                + LanguagesConstants.LANGUAGE
                        .getString(LanguagesConstants.STATION_LOADING_TIME)
                + " : " + this.loadingTime ;
        return toReturn;
    }

    public String toHTMLWithColors() {
        return "<h4 style=\"color:red\">"
                + this.address
                + " </h4> "
                + "<h4 style=\"color:#FFA500\">"
                + LanguagesConstants.LANGUAGE
                        .getString(LanguagesConstants.HOURS)
                + " : "
                + this.opening
                + "-"
                + this.closing
                + " </h4> "
                + "<h4 style=\"color:#800080\"> "
                + LanguagesConstants.LANGUAGE
                        .getString(LanguagesConstants.STATION_LOADING_TIME)
                + " : " + this.loadingTime + " </h4> ";
    }

    @Override
    public String toString() {
        return this.address
                + LanguagesConstants.LANGUAGE
                        .getString(LanguagesConstants.HOURS)
                + " : "
                + this.opening
                + "-"
                + this.closing
                + " && "
                + LanguagesConstants.LANGUAGE
                        .getString(LanguagesConstants.STATION_LOADING_TIME)
                + " : " + this.loadingTime;
    }

    /**
     * @param d
     *            the document where the element should be add.
     * @return a new Element which can be add to d
     */
    public Element toXML(Document d) {
        return this.toXML(d, "station");
    }

    /**
     * @param d
     *            the document where the element should be add.
     * @param name
     *            the root name.
     * @return the new Element which can be add to d.
     */
    public Element toXML(Document d, String name) {
        Element root = d.createElement(name);
        root.appendChild(this.getAddress().toXML(d));
        DOMParser.getElementAppended(d, "loadingTime", this.getLoadingTime()
                + "", root);
        root.appendChild(this.getOpening().toXML(d, "opening"));
        root.appendChild(this.getClosing().toXML(d, "closing"));
        return root;
    }
}
